package container

import (
	"JoDocker/util"
	"github.com/Sirupsen/logrus"
	"os"
	"os/exec"
)

// 数据卷挂载 使用bind方式挂载 --需要使用root权限创建文件
func mountVolumeForBind(mntPath string, volumeSlc []string) {
	hostPath, containerPath := mkVolumeDir(mntPath, volumeSlc)
	if _, err := exec.Command("mount", "-o", "bind", hostPath, containerPath).CombinedOutput(); err != nil {
		logrus.Errorf("error => mount bind error %v", err)
	}
}

// 取消数据卷挂载 -- 会自动把容器里挂载的目录下的文件夹/文件删除, 但主机目录下的文件夹/文件会保留
func umountVolumeForBind(mntPath string, volumeSlc []string) {
	containerPath := mntPath + volumeSlc[1]
	if _, err := exec.Command("umount", containerPath).CombinedOutput(); err != nil {
		logrus.Errorf("error => umount bind error %v", err)
	}
}

// 创建数据卷目录
func mkVolumeDir(mntPath string, volumeSlc []string) (string, string) {
	// 主机路径
	hostPath := volumeSlc[0]
	if err := os.MkdirAll(hostPath, 0777); err != nil {
		logrus.Infof("error => Mkdir parent dir %s error. %v", hostPath, err)
	}
	// 容器内部路径
	containerPath := mntPath + volumeSlc[1]
	if err := os.MkdirAll(containerPath, 0777); err != nil {
		logrus.Infof("error => Mkdir container dir %s error. %v", containerPath, err)
	}
	return hostPath, containerPath
}

// 数据卷挂载 使用 overlay方式挂载 -- 使用overlay方式挂载的话会把主机目录上原来的数据删除掉--不使用
func mountVolume(mntPath string, volumeSlc []string) {

	logrus.Infof("当前使用 overlay 挂载数据卷")

	hostPath, containerPath := mkVolumeDir(mntPath, volumeSlc)

	// 临时文件系统挂载
	if _, err := exec.Command("mount", "-t", "tmpfs", "tmpfs", hostPath).CombinedOutput(); err != nil {
		logrus.Errorf("error => mount tmpfs %s error %v", hostPath, err)
	}

	writeDirPath := hostPath + "/data/"
	workDirPath := hostPath + "/work/"
	util.MkDirAll(writeDirPath)
	util.MkDirAll(workDirPath)

	// 读层 -- 空目录
	volumeReadPath := RootPath + "volumeonly/"
	readDirPath := volumeReadPath
	util.MkDirAll(readDirPath)

	// 读写层
	lowerDir := "lowerdir=" + readDirPath
	upperDir := "upperdir=" + writeDirPath
	workDir := "workdir=" + workDirPath
	dirs := lowerDir + "," + upperDir + "," + workDir
	if _, err := exec.Command("mount", "-t", "overlay", "overlay", "-o", dirs, containerPath).CombinedOutput(); err != nil {
		logrus.Errorf("error => mount overlay %v", err)
	}
}

// 取消数据卷挂载 -- 取消挂载时会取消失败  -- 不使用
func umountVolume(mntPath string, volumeSlc []string) {
	logrus.Infof("当前使用 overlay 取消挂载数据卷")
	if len(volumeSlc) == 2 && volumeSlc[0] != "" && volumeSlc[1] != "" {
		containerPath := mntPath + volumeSlc[1]

		hostPath := volumeSlc[0]
		if _, err := exec.Command("umount", hostPath).CombinedOutput(); err != nil {
			logrus.Errorf("error => umount volume failed. %s error.%v", hostPath, err)
		}

		if _, err := exec.Command("umount", containerPath).CombinedOutput(); err != nil {
			logrus.Errorf("error => umount volume failed. %s error.%v", containerPath, err)
		}
	}
}
